package com.example.edupublisher.controller;

import com.example.edupublisher.bean.*;
import com.example.edupublisher.service.TrafficKeywordsService;
import com.example.edupublisher.service.TrafficSourceStatsService;
import com.example.edupublisher.service.TrafficVisitorStatsService;
import com.example.edupublisher.util.DateFormatUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.List;

/**
 * ClassName: TrafficSourceController
 * Package: com.atguigu.edu.publisher.controller
 * Description:
 * 这次Controller 按文档来一次
 * @Author Mr.2
 * @Create 2023/9/11 10:58
 * @Version 1.0
 */
@RestController
@RequestMapping("/edu/realtime/traffic")
public class TrafficSourceController {
    // 自动装载来源流量统计服务实现类
    @Autowired
    private TrafficSourceStatsService trafficSourceStatsService;

    // 自动装载访客状态统计服务实现类
    @Autowired
    private TrafficVisitorStatsService trafficVisitorStatsService;

    // 自动装载 关键词服务接口类型
    @Autowired
    private TrafficKeywordsService trafficKeywordsService;


    // 1. 独立访客请求拦截方法
    @RequestMapping("/sc/uvCt")
    public String getUvCt(@RequestParam(value = "date", defaultValue = "1") Integer date) {
        //
        if (date == 1) {
            date = DateFormatUtil.now();
        }

        List<TrafficScUvCt> trafficScUvCtList = trafficSourceStatsService.getUvCt(date);
        if (trafficScUvCtList == null) {
            return "";
        }
        StringBuilder categories = new StringBuilder("[");
        StringBuilder uvCtValues = new StringBuilder("[");

        for (int i = 0; i < trafficScUvCtList.size(); i++) {
            TrafficScUvCt trafficScUvCt = trafficScUvCtList.get(i);
            String sc = trafficScUvCt.getSc();
            Integer uvCt = trafficScUvCt.getUvCt();

            categories.append("\"").append(sc).append("\"");
            uvCtValues.append("\"").append(uvCt).append("\"");
            // 中间分隔符
            if (i < trafficScUvCtList.size() - 1) {
                categories.append(",");
                uvCtValues.append(",");
            } else {
                categories.append("]");
                uvCtValues.append("]");
            }

        }

        return "{\n" +
                "  \"status\": 0,\n" +
                "  \"msg\": \"\",\n" +
                "  \"data\": {\n" +
                "    \"categories\":" + categories + ",\n" +
                "    \"series\": [\n" +
                "      {\n" +
                "        \"name\": \"独立访客数\",\n" +
                "        \"data\": " + uvCtValues + "\n" +
                "      }\n" +
                "    ]\n" +
                "  }\n" +
                "}";

    }

    // 2. 会话数请求拦截方法
    @RequestMapping("/sc/svCt")
    public String getSvCt(@RequestParam(value = "date", defaultValue = "1") Integer date) {
        //
        if (date == 1) {
            date = DateFormatUtil.now();
        }
        List<TrafficScSvCt> trafficScSvCtList = trafficSourceStatsService.getSvCt(date);
        if (trafficScSvCtList == null) {
            return "";
        }

        StringBuilder categories = new StringBuilder("[");
        StringBuilder svCtValues = new StringBuilder("[");

        for (int i = 0; i < trafficScSvCtList.size(); i++) {
            TrafficScSvCt trafficScSvCt = trafficScSvCtList.get(i);
            String sc = trafficScSvCt.getSc();
            Integer svCt = trafficScSvCt.getSvCt();

            categories.append("\"").append(sc).append("\"");
            svCtValues.append("\"").append(svCt).append("\"");
            // 中间分隔符
            if (i < trafficScSvCtList.size() - 1) {
                categories.append(",");
                svCtValues.append(",");
            } else {
                categories.append("]");
                svCtValues.append("]");
            }

        }
        return "{\n" +
                "  \"status\": 0,\n" +
                "  \"msg\": \"\",\n" +
                "  \"data\": {\n" +
                "    \"categories\":" + categories + ",\n" +
                "    \"series\": [\n" +
                "      {\n" +
                "        \"name\": \"会话数\",\n" +
                "        \"data\": " + svCtValues + "\n" +
                "      }\n" +
                "    ]\n" +
                "  }\n" +
                "}";
    }

    // 3. 各会话浏览页面数请求拦截方法
    @RequestMapping("/sc/pvPerSession")
    public String getPvPerSession(@RequestParam(value = "date", defaultValue = "1") Integer date) {
        //
        if (date == 1) {
            date = DateFormatUtil.now();
        }

        List<TrafficScPvPerSession> trafficScPvPerSessionList = trafficSourceStatsService.getPvPerSession(date);
        if (trafficScPvPerSessionList == null) {
            return "";
        }

        StringBuilder categories = new StringBuilder("[");
        StringBuilder pvPerSessionValues = new StringBuilder("[");

        for (int i = 0; i < trafficScPvPerSessionList.size(); i++) {
            TrafficScPvPerSession trafficScPvPerSession = trafficScPvPerSessionList.get(i);
            String sc = trafficScPvPerSession.getSc();
            BigDecimal pvPerSession = trafficScPvPerSession.getPvPerSession();

            categories.append("\"").append(sc).append("\"");
            pvPerSessionValues.append("\"").append(pvPerSession).append("\"");

            // 中间分隔符
            if (i < trafficScPvPerSessionList.size() - 1) {
                categories.append(",");
                pvPerSessionValues.append(",");
            } else {  //
                categories.append("]");
                pvPerSessionValues.append("]");
            }
        }

        return "{\n" +
                "  \"status\": 0,\n" +
                "  \"msg\": \"\",\n" +
                "  \"data\": {\n" +
                "    \"categories\":" + categories + ",\n" +
                "    \"series\": [\n" +
                "      {\n" +
                "        \"name\": \"会话平均页面浏览数\",\n" +
                "        \"data\": " + pvPerSessionValues + "\n" +
                "      }\n" +
                "    ]\n" +
                "  }\n" +
                "}";
    }

    // 4. 各会话累计访问时长请求拦截方法
    @RequestMapping("/sc/durPerSession")
    public String getDurPerSession(@RequestParam(value = "date", defaultValue = "1") Integer date) {
        //
        if (date == 1) {
            date = DateFormatUtil.now();
        }
        List<TrafficScDurPerSession> trafficScDurPerSessionList = trafficSourceStatsService.getDurPerSession(date);
        if (trafficScDurPerSessionList == null) {
            return "";
        }

        // 以 拼接JSONString的形式返回, json
        StringBuilder categories = new StringBuilder("[");
        StringBuilder durPerSessionValues = new StringBuilder("[");

        for (int i = 0; i < trafficScDurPerSessionList.size(); i++) {
            TrafficScDurPerSession trafficScDurPerSession = trafficScDurPerSessionList.get(i);
            String sc = trafficScDurPerSession.getSc();
            BigDecimal durPerSession = trafficScDurPerSession.getDurPerSession();

            categories.append("\"").append(sc).append("\"");
            durPerSessionValues.append("\"").append(durPerSession).append("\"");

            if (i < trafficScDurPerSessionList.size() - 1) {
                categories.append(",");
                durPerSessionValues.append(",");
            } else {
                categories.append("]");
                durPerSessionValues.append("]");
            }

        }

        return "{\n" +
                "  \"status\": 0,\n" +
                "  \"msg\": \"\",\n" +
                "  \"data\": {\n" +
                "    \"categories\":" + categories + ",\n" +
                "    \"series\": [\n" +
                "      {\n" +
                "        \"name\": \"会话平均页面访问时长\",\n" +
                "        \"data\": " + durPerSessionValues + "\n" +
                "      }\n" +
                "    ]\n" +
                "  }\n" +
                "}";
    }

    // 5. 跳出率请求拦截方法
    @RequestMapping("/sc/ujRate")
    public String getUjRate(@RequestParam(value = "date", defaultValue = "1") Integer date) {
        //
        if (date == 1) {
            date = DateFormatUtil.now();
        }

        List<TrafficScUjRate> trafficScUjRateList = trafficSourceStatsService.getUjRate(date);
        if (trafficScUjRateList == null) {
            return "";
        }

        StringBuilder categories = new StringBuilder("[");
        StringBuilder ujRateValues = new StringBuilder("[");

        for (int i = 0; i < trafficScUjRateList.size(); i++) {
            TrafficScUjRate trafficScUjRate = trafficScUjRateList.get(i);
            String sc = trafficScUjRate.getSc();
            BigDecimal ujRate = trafficScUjRate.getUjRate();

            categories.append("\"").append(sc).append("\"");
            ujRateValues.append("\"").append(ujRate).append("\"");

            if (i < trafficScUjRateList.size() - 1) {
                categories.append(",");
                ujRateValues.append(",");
            } else {
                categories.append("]");
                ujRateValues.append("]");
            }
        }

        return "{\n" +
                "  \"status\": 0,\n" +
                "  \"msg\": \"\",\n" +
                "  \"data\": {\n" +
                "    \"categories\":" + categories + ",\n" +
                "    \"series\": [\n" +
                "      {\n" +
                "        \"name\": \"跳出率\",\n" +
                "        \"data\": " + ujRateValues + "\n" +
                "      }\n" +
                "    ]\n" +
                "  }\n" +
                "}";
    }

    // 6. 访客状态分时统计请求拦截方法
    @RequestMapping("/visitorPerHr")
    public String getVisitorPerHr(@RequestParam(value = "date",defaultValue = "1") Integer date) {
        if (date == 1) {
            date = DateFormatUtil.now();
        }

        List<TrafficVisitorStatsPerHour> visitorStatsPerHourList = trafficVisitorStatsService.getVisitorPerHrStats(date);
        if (visitorStatsPerHourList == null || visitorStatsPerHourList.size() == 0) {
            return "";
        }

        // 1天24小时
        TrafficVisitorStatsPerHour[] perHrArr = new TrafficVisitorStatsPerHour[24];
        for (TrafficVisitorStatsPerHour trafficVisitorStatsPerHour : visitorStatsPerHourList) {
            //
            Integer hr = trafficVisitorStatsPerHour.getHr();
            //
            perHrArr[hr] = trafficVisitorStatsPerHour;
        }

        String[] hrs = new String[24];
        Long[] uvArr = new Long[24];
        Long[] pvArr = new Long[24];
        Long[] newUvArr = new Long[24];
        Long[] avgPerSessionArr = new Long[24];

        for (int hr = 0; hr < 24; hr++) {
            //
            hrs[hr] = String.format("%02d", hr);
            TrafficVisitorStatsPerHour trafficVisitorStatsPerHour = perHrArr[hr];
            //
            if (trafficVisitorStatsPerHour != null) {
                uvArr[hr] = trafficVisitorStatsPerHour.getUvCt();
                pvArr[hr] = trafficVisitorStatsPerHour.getPvCt();
                newUvArr[hr] = trafficVisitorStatsPerHour.getNewUvCt();
                avgPerSessionArr[hr] = trafficVisitorStatsPerHour.getPerPvSession();
            } else {
                uvArr[hr] = 0L;
                pvArr[hr] = 0L;
                newUvArr[hr] = 0L;
                avgPerSessionArr[hr] = 0L;
            }
        }

        return "{\n" +
                "  \"status\": 0,\n" +
                "  \"msg\": \"\",\n" +
                "  \"data\": {\n" +
                "    \"categories\": [\n\"" +
                StringUtils.join(hrs, "\",\"") + "\"\n" +
                "    ],\n" +
                "    \"series\": [\n" +
                "      {\n" +
                "        \"name\": \"独立访客数\",\n" +
                "        \"data\": [\n" +
                StringUtils.join(uvArr, ",") + "\n" +
                "        ]\n" +
                "      },\n" +
                "      {\n" +
                "        \"name\": \"页面浏览数\",\n" +
                "        \"data\": [\n" +
                StringUtils.join(pvArr, ",") + "\n" +
                "        ]\n" +
                "      },\n" +
                "      {\n" +
                "        \"name\": \"新访客数\",\n" +
                "        \"data\": [\n" +
                StringUtils.join(newUvArr, ",") + "\n" +
                "        ]\n" +
                "      },\n" +
                "      {\n" +
                "        \"name\": \"会话平均页面浏览数\",\n" +
                "        \"data\": [\n" +
                StringUtils.join(avgPerSessionArr, ",") + "\n" +
                "        ]\n" +
                "      }\n" +
                "    ]\n" +
                "  }\n" +
                "}";
    }

    // 7. 新老访客流量统计 请求拦截方法
    @RequestMapping("/visitorPerType")
    public String getVisitorPerType(@RequestParam(value = "date", defaultValue = "1") Integer date) {

        if (date == 1) {
            date = DateFormatUtil.now();
        }

        List<TrafficVisitorTypeStats> visitorTypeStatsList = trafficVisitorStatsService.getVisitorTypeStats(date);
        // 若得到的集合为空,则处理, 并返回"",在sugar里展示
        if (visitorTypeStatsList == null || visitorTypeStatsList.size() == 0) {
            return "";
        }

        // 方法一：通过循环的方式拼接字符串，较为繁琐，不推荐
        // 方法二，直接拼接字符串，简单明了
        TrafficVisitorTypeStats newVisitorStats = null;
        TrafficVisitorTypeStats oldVisitorStats = null;

        for (TrafficVisitorTypeStats visitorTypeStats : visitorTypeStatsList) {
            // 上来先输出一下, 看下结果
            System.out.println(visitorTypeStats);
            if ("1".equals(visitorTypeStats.getIsNew())) {
                // 新访客
                newVisitorStats = visitorTypeStats;
            } else {
                oldVisitorStats = visitorTypeStats;
            }

        }

        //拼接json字符串
        String json = "{\"status\":0,\"data\":{\"total\":5," +
                "\"columns\":[" +
                "{\"name\":\"类别\",\"id\":\"type\"}," +
                "{\"name\":\"新访客\",\"id\":\"new\"}," +
                "{\"name\":\"老访客\",\"id\":\"old\"}]," +
                "\"rows\":[" +
                "{\"type\":\"访客数(人)\",\"new\":" + newVisitorStats.getUvCt() + ",\"old\":" + oldVisitorStats.getUvCt() + "}," +
                "{\"type\":\"总访问页面数(次)\",\"new\":" + newVisitorStats.getPvCt() + ",\"old\":" + oldVisitorStats.getPvCt() + "}," +
                "{\"type\":\"跳出率(%)\",\"new\":" + newVisitorStats.getUjRate() + ",\"old\":" + oldVisitorStats.getUjRate() + "}," +
                "{\"type\":\"平均在线时长(秒)\",\"new\":" + newVisitorStats.getAvgDurSum() + ",\"old\":" + oldVisitorStats.getAvgDurSum() + "}," +
                "{\"type\":\"平均访问页面数(人次)\",\"new\":" + newVisitorStats.getAvgPvCt() + ",\"old\":" + oldVisitorStats.getAvgPvCt() + "}]}}";

        return json;

    }

    // 8. 关键词统计 请求拦截方法
    @RequestMapping("/keywords")
    public String getKeywords(@RequestParam(value = "date", defaultValue = "1") Integer date) {

        if (date == 1) {
            date = DateFormatUtil.now();
        }

        List<TrafficKeywords> keywordsList = trafficKeywordsService.getKeywords(date);
        if (keywordsList == null) {
            return "";
        }

        StringBuilder data = new StringBuilder("[");

        for (int i = 0; i < keywordsList.size(); i++) {
            TrafficKeywords trafficKeywords = keywordsList.get(i);
            String keyword = trafficKeywords.getKeyword();
            Integer keywordCount = trafficKeywords.getKeywordCount();

            // 拼接 json
            data.append("" +
                    "{\n" +
                    "      \"name\": \"" + keyword + "\",\n" +
                    "      \"value\": " + keywordCount + "\n" +
                    "    }");

            if (i < keywordsList.size() - 1) {
                data.append(",");
            } else {
                data.append("]");
            }

        }
        // 返回 json
        return "{\n" +
                "  \"status\": 0,\n" +
                "  \"msg\": \"\",\n" +
                "  \"data\": " + data + "\n" +
                "}";
    }

}

